package cn.edu.jxau.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Objects;

/**
 * CSV字典
 * @author 付大石
 */
public class CSVDictionary {

    public static void main(String[] args) throws IOException {

        CSVDictionary st = new CSVDictionary(new File("C:\\Users\\PC-Clive\\Desktop\\data.csv"));
        st.append(new File("C:\\Users\\PC-Clive\\Desktop\\data.csv"), 1, 0, ",");
        System.out.println(st);
    }

    private SeparateChainingHashST<String, String> st;
    private int keyIndex;
    private int valueIndex;

    public CSVDictionary(File csvFile) throws IOException {
        this(csvFile, ",");
    }

    public CSVDictionary(File csvFile, String regex) throws IOException {
        this(csvFile, 0, 1, regex);
    }

    /**
     * @param csvFile 要读取的.csv文件
     * @param keyIndex key所在的索引值
     * @param valueIndex value所在的索引值
     * @param regex 分隔符，用于分割一行的数据
     * @throws IOException 
     */
    public CSVDictionary(File csvFile, int keyIndex, int valueIndex, String regex) throws IOException {

        // 参数校验 //
        check(csvFile, keyIndex, valueIndex, regex);

        // 读取数据 //
        st = new SeparateChainingHashST<String, String>();
        this.keyIndex = keyIndex;
        this.valueIndex = valueIndex;
        read(csvFile, keyIndex, valueIndex, regex);
    }

    private void check(File csvFile, int keyIndex, int valueIndex, String regex) throws IOException {

        Objects.requireNonNull(csvFile, "参数csvFile不能为null");
        if (!csvFile.getName().endsWith(".csv")) {
            throw new IOException("文件类型错误，仅支持.csv文件，文件路径：" + csvFile.getCanonicalPath());
        }
        if (!csvFile.exists()) {
            throw new IOException("文件不存在，文件路径：" + csvFile.getCanonicalPath());
        }
        if (!csvFile.isFile()) {
            throw new IOException("不可指定一个文件夹，文件路径：" + csvFile.getCanonicalPath());
        }
        if (!csvFile.canRead()) {
            throw new IOException("文件不可读，文件路径：" + csvFile.getCanonicalPath());
        }
        Objects.requireNonNull(regex, "参数regex不能为null");
        if (keyIndex < 0) {
            throw new IllegalArgumentException("参数keyIndex不能为负数");
        }
        if (valueIndex < 0) {
            throw new IllegalArgumentException("参数valueIndex不能为负数");
        }
    }

    private void read(File csvFile, int keyIndex, int valueIndex, String regex) throws IOException {

        try (FileReader fileReader = new FileReader(csvFile);
                BufferedReader reader = new BufferedReader(new FileReader(csvFile))) {
            String line = null;
            String[] data = null;
            while ((line = reader.readLine()) != null) {
                data = line.split(regex);
                st.put(data[keyIndex], data[valueIndex]);
            }
        } catch (IOException e) {
            throw new IOException("文件读取失败，文件路径：" + csvFile.getCanonicalPath(), e);
        }
    }

    public String get(String key) {
        return st.get(key);
    }

    public void append(File csvFile) throws IOException {
        append(csvFile, ",");
    }

    public void append(File csvFile, String regex) throws IOException {
        append(csvFile, 0, 1, regex);
    }

    public void append(File csvFile, int keyIndex, int valueIndex, String regex) throws IOException {
        check(csvFile,keyIndex,valueIndex,regex);
        read(csvFile, keyIndex, valueIndex, regex);
    }

    @Override
    public String toString() {

        StringBuilder sb = new StringBuilder();
        for (String key : st.keys()) {
            sb.append(key + "-" + st.get(key) + "\t");
        }
        if (st.size() != 0) {
            sb.deleteCharAt(sb.length() - 1); // 删除最后的制表符
        }
        return sb.toString();
    }
}
